﻿// <copyright file="DateTimeTypeConverter.cs" company="Microsoft Corporation">
// Copyright (c) 2008 All Right Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2009-03-06</date>
// <summary>DateTime Type converter</summary>

namespace Synergist
{
    using System;
    using System.ComponentModel;
    using System.Globalization;

    /// <summary>
    /// Type converter for DateTime properties in CLR objects
    /// </summary>
    /// Use this for all properties with DateTime types that are exposed in CLR objects
    /// <example>
    /// This is from the <see cref="NYTimes.CommunityCommentsByDate"/> class:
    /// <code>
    /// using System.ComponentModel;
    /// using Synergist;
    /// public class CommunityCommentsByDate
    /// {
    ///     ...
    ///     [TypeConverter(typeof(Synergist.DateTimeTypeConverter))]
    ///     public DateTime Date { get; set; }
    ///     ...
    /// }
    /// </code>
    /// </example>
    public class DateTimeTypeConverter : TypeConverter
    {
        /// <summary>
        /// Can convert from a type
        /// </summary>
        /// <param name="context">the type description context</param>
        /// <param name="sourceType">the source type</param>
        /// <returns>true if the coversion can happen</returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == null)
            {
                throw new ArgumentNullException("sourceType");
            }

            if (sourceType.Equals(typeof(string)))
            {
                return true;
            }
            else
            {
                return base.CanConvertFrom(context, sourceType);
            }
        }

        /// <summary>
        /// Can convert to a type
        /// </summary>
        /// <param name="context">the context</param>
        /// <param name="destinationType">the destination type</param>
        /// <returns>true if the conversion can work</returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }

            if (destinationType.Equals(typeof(string)))
            {
                return true;
            }
            else
            {
                return base.CanConvertTo(context, destinationType);
            }
        }

        /// <summary>
        /// Convert from a type
        /// </summary>
        /// <param name="context">An object that provides a format context. </param>
        /// <param name="culture">The CultureInfo to use as the current culture.</param>
        /// <param name="value">The value to convert to the type of this converter. </param>
        /// <returns>the converted value</returns>
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                try
                {
                    return DateTime.Parse(value.ToString(), culture);
                }
                catch
                {
                    throw new NotSupportedException();
                }
            }
            else
            {
                return base.ConvertFrom(context, culture, value);
            }
        }

        /// <summary>
        /// Convert to the destination type
        /// </summary>
        /// <param name="context">An object that provides a format context.</param>
        /// <param name="culture">The CultureInfo to use as the current culture.</param>
        /// <param name="value">The object to convert</param>
        /// <param name="destinationType">The type to convert the object to.</param>
        /// <returns>the converted object</returns>
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");
            }

            if (value == null)
            {
                return null;
            }

            if (destinationType.Equals(typeof(string)))
            {
                return value.ToString();
            }
            else
            {
                return base.ConvertTo(context, culture, value, destinationType);
            }
        }
    }
}
